package org.devastra.arcinspect.analyzer;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.ZipException;

import org.devastra.arcinspect.analyzer.data.ProjectData;
import org.devastra.arcinspect.analyzer.parser.FileParser;
import org.devastra.arcinspect.core.data.LibraryElementInfo;
import org.devastra.arcinspect.core.util.FileUtil;

public class ProjectAnalyzer {

	/**
	 * @param args
	 */
	
	private ProjectData projData;
	
	public ProjectAnalyzer(ProjectData _projData) {
		projData = _projData;
		
	}
	
	public ProjectData analyze() {
		locateLibraries();
		analyzeLibraries();
		locateSourceFolder(new File(projData.getBaseFolder()));
		analyzeSourceFiles();
		
		return projData;
	}
	
	/**
	 * Scan the project files to find the jar files. Currently libraries packaged as zip file
	 * are not supported.
	 */
	public void locateLibraries() {
		List<File> projectFolders = new ArrayList<File>();
		projectFolders.add(new File(projData.getBaseFolder()));
		
		while(projectFolders.size() > 0)  {
			File folder = projectFolders.remove(0);
			
			File[] children = folder.listFiles();
			for(File child : children) {
				if(child.isDirectory()) {
					projectFolders.add(child);
					continue;
				} else if (child.getName().endsWith(".jar")) {
					projData.addLibrary(child);
				}
			}
		}
		
	}
	
	public void analyzeLibraries() {
		for(File libFile : projData.getProjectLibraries()) {
			analyzeLibrary(libFile);
		}
	}
	
	/**
	 * Read the library entries and identify the packages and elements.
	 * 
	 * @param _jarFile
	 */
	public void analyzeLibrary(File _jarFile) {
		
		try {
			JarFile jarFile = new JarFile(_jarFile); 
			Enumeration<JarEntry> jarEntries = jarFile.entries();
			while(jarEntries.hasMoreElements()) {
				JarEntry entry = jarEntries.nextElement();
				//EntityInfo elem = LibraryElementInfo.getLibaryElement(entry.getName());
				LibraryElementInfo.getLibaryElement(entry.getName());
			}
		} catch (ZipException e) {
			System.out.println("Error opening zip file: "+_jarFile.getAbsolutePath());
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void locateSourceFolder(File _folder) {
		
		File[] children = _folder.listFiles();
		
		//File[] children = projData.getBaseFolder().`
		for(File child : children) {
			if(child.isDirectory()) {
				if("com".equals(child.getName()) || "org".equals(child.getName())) {
					projData.addSrcFolders(_folder);
					return;
				}
				
				locateSourceFolder(child);
			} else {
				if(child.getName().endsWith("*.java")) {
					projData.addSrcFolders(_folder);
					return;
				}
			}
			
		}
		
	}

	private void analyzeSourceFiles() {
		for(File srcFolder : projData.getSourceFolders()) {
			analyzeSourceFiles(srcFolder);
		}
	}
	
	private void analyzeSourceFiles(File _folder) {
		
		File[] children = _folder.listFiles();
		for(File child : children) {
			if(child.isDirectory()) {
				analyzeSourceFiles(child);
			} else if(child.getName().endsWith(".java")) {
				List<String> srcCode;
				try {
					srcCode = FileUtil.getLines(child);
					FileParser.getEntityInfo(srcCode);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
	
//	public static void main_test_Jar(String[] args) {
//		File f = new File("/home/ashutosh/projects/openbrr/server/lib/java/Tidy.jar");
//		if(!f.exists()) {
//			System.out.println("File does not exist");
//			return;
//		}
//		
//		ProjectAnalyzer pa = new ProjectAnalyzer("", null);
//		pa.analyzeLibrary(f);
//	}
}
